package com.zjhn.ds.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zjhn.ds.common.BizResult;
import com.zjhn.ds.common.PageResult;
import com.zjhn.ds.domain.dto.pc.EquipmentDto;
import com.zjhn.ds.domain.dto.pc.StationDto;
import com.zjhn.ds.domain.entity.jlw.BindInfo;
import com.zjhn.ds.domain.entity.jlw.Equipment;
import com.zjhn.ds.domain.entity.jlw.GroupStation;
import com.zjhn.ds.domain.entity.jlw.Station;
import com.zjhn.ds.domain.vo.EquipmentVo;
import com.zjhn.ds.domain.vo.StationVo;
import com.zjhn.ds.mapper.BindInfoMapper;
import com.zjhn.ds.mapper.EquipmentMapper;
import com.zjhn.ds.mapper.GroupStationMapper;
import com.zjhn.ds.mapper.StationMapper;
import com.zjhn.ds.param.AddUpdateEquipmentParam;
import com.zjhn.ds.param.AddUpdateStationParam;
import com.zjhn.ds.param.EquipmentPageParam;
import com.zjhn.ds.param.StationPageParam;
import com.zjhn.ds.service.DeviceService;
import com.zjhn.ds.utils.CommonUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Comparator;

/**
 * @BelongsProject: ds_jlw
 * @BelongsPackage: com.zjhn.ds.service.impl
 * @Author: sxt
 * @CreateTime: 2023-09-14  15:37
 * @Description:
 * @Version: 1.0
 */
@Service
public class DeviceServiceImpl implements DeviceService {

    @Resource
    private CommonUtil commonUtil;

    @Resource
    private EquipmentMapper equipmentMapper;

    @Resource
    private BindInfoMapper bindInfoMapper;

    @Resource
    private StationMapper stationMapper;

    @Resource
    private GroupStationMapper groupStationMapper;

    /**
     * 新增/更新设备机台信息
     *
     * @param param
     * @return
     */
    @Override
    public BizResult<?> addUpdateEquipment(AddUpdateEquipmentParam param) {
        Equipment equipment;
        if (StringUtils.isNotBlank(param.getEquipmentId())) {
            // 更新
            equipment = equipmentMapper.selectById(param.getEquipmentId());
            if (equipment == null)
                return BizResult.fail("设备信息不存在");

            Integer count = equipmentMapper.selectCount(
                    new QueryWrapper<Equipment>()
                            .eq("equipment_name", param.getEquipmentName())
                            .ne("id", equipment.getId()));
            if (count > 0)
                return BizResult.fail("设备名称已存在");

            equipment.setEquipmentName(param.getEquipmentName());
            equipment.setWorkshopId(param.getWorkshopId());
            equipment.setEquipmentTypeId(param.getEquipmentTypeId());
            equipment.setModelId(equipment.getModelId());
            equipment.setNeedleCode(equipment.getNeedleCode());
            equipment.setNeedleNumber(equipment.getNeedleNumber());
            equipment.setStockingsCode(param.getStockingsCode());
            equipment.setOutreachDevice(param.getOutreachDevice());
            equipment.setOutreachType(param.getOutreachType());
            equipmentMapper.updateById(equipment);
        } else {
            // 新增
            equipment = equipmentMapper.selectOne(
                    new QueryWrapper<Equipment>()
                            .eq("equipment_name", param.getEquipmentName()));
            if (equipment != null)
                return BizResult.fail("设备名称已存在");

            equipment = Equipment.builder()
                    .equipmentName(param.getEquipmentName())
                    .workshopId(param.getWorkshopId())
                    .equipmentTypeId(param.getEquipmentTypeId())
                    .modelId(param.getModelId())
                    .needleNumber(param.getNeedleNumber())
                    .needleCode(param.getNeedleCode())
                    .stockingsCode(param.getStockingsCode())
                    .outreachDevice(param.getOutreachDevice())
                    .outreachType(param.getOutreachType())
                    .build();
            equipmentMapper.insert(equipment);
        }

        // redis 更新
        commonUtil.updateEquipmentInfo(
                equipment.getId(),
                EquipmentVo.builder()
                        .id(equipment.getId())
                        .equipmentName(equipment.getEquipmentName())
                        .equipmentTypeId(equipment.getEquipmentTypeId())
                        .modelId(equipment.getModelId())
                        .needleCode(equipment.getNeedleCode())
                        .needleNumber(equipment.getNeedleNumber())
                        .stockingsCode(equipment.getStockingsCode())
                        .outreachDevice(equipment.getOutreachDevice())
                        .outreachType(equipment.getOutreachType())
                        .build());
        return BizResult.success();
    }

    /**
     * 删除设备机台
     *
     * @param equipmentId
     * @return
     */
    @Override
    public BizResult<?> removeEquipment(String equipmentId) {
        Equipment equipment = equipmentMapper.selectById(equipmentId);
        if (equipment == null)
            return BizResult.success();

        Integer count = bindInfoMapper.selectCount(new QueryWrapper<BindInfo>().eq("equipment_id", equipmentId));
        if (count > 0)
            return BizResult.fail("设备机台已绑定工位");

        equipmentMapper.deleteById(equipmentId);
        commonUtil.removeEquipmentInfo(equipmentId);

        return BizResult.success();
    }

    /**
     * 按条件分页查询设备机台信息
     *
     * @param param
     * @return
     */
    @Override
    public BizResult<PageResult<EquipmentDto>> equipmentPage(EquipmentPageParam param) {
        QueryWrapper<Equipment> queryWrapper = new QueryWrapper<>();
        if (StringUtils.isNotBlank(param.getEquipmentName()))
            queryWrapper.like("equipment_name", param.getEquipmentName());
        if (StringUtils.isNotBlank(param.getStockingsCode()))
            queryWrapper.like("stockings_code", param.getStockingsCode());
        if (StringUtils.isNotBlank(param.getNeedleNumber()))
            queryWrapper.like("needle_number", param.getNeedleNumber());
        if (StringUtils.isNotBlank(param.getNeedleCode()))
            queryWrapper.like("needle_code", param.getNeedleCode());
        Page<Equipment> page = equipmentMapper.selectPage(
                new Page<>(param.getCurrent(), param.getSize()),
                queryWrapper.orderByAsc("create_time")
        );

        IPage<EquipmentDto> convert = page.convert(c ->
                EquipmentDto.builder()
                        .equipmentId(c.getId())
                        .equipmentName(c.getEquipmentName())
                        .workshop(commonUtil.getWorkshopById(c.getWorkshopId()))
                        .modelId(c.getModelId())
                        .modelName(commonUtil.getModelById(c.getModelId()).getModelName())
                        .equipmentTypeId(c.getEquipmentTypeId())
                        .typeName(commonUtil.getEquipmentTypeById(c.getEquipmentTypeId()))
                        .needleCode(c.getNeedleCode())
                        .needleNumber(c.getNeedleNumber())
                        .stockingsCode(c.getStockingsCode())
                        .outreachDevice(c.getOutreachDevice())
                        .outreachType(c.getOutreachType())
                        .build());
        PageResult<EquipmentDto> res = PageResult.<EquipmentDto>builder()
                .current(convert.getCurrent())
                .pages(convert.getPages())
                .size(convert.getSize())
                .build();
        if (convert.getRecords().size() > 0) {
            convert.getRecords().sort(Comparator.comparing(c -> Integer.parseInt(c.getEquipmentName())));
            res.setRecord(convert.getRecords());
        }
        return BizResult.success(res);
    }

    /**
     * 新增/更新工位信息
     *
     * @param param
     * @return
     */
    @Override
    @Transactional
    public BizResult<?> addUpdateStation(AddUpdateStationParam param) {
        Station station;
        if (StringUtils.isNotBlank(param.getStationId())) {
            // 更新
            station = stationMapper.selectById(param.getStationId());
            if (station == null)
                return BizResult.fail("工位不存在");

            Integer count = stationMapper.selectCount(new QueryWrapper<Station>()
                    .eq("station_code", param.getStationCode())
                    .eq("station_name", param.getStationName())
                    .ne("id", param.getStationId()));
            if (count > 0)
                return BizResult.fail("工位名称或工位编号已存在");

            String[] split = param.getStationCode().split("-");
            station.setWorkshopId(param.getWorkshopId());
            station.setStationName(param.getStationName());
            station.setStationCode(param.getStationCode());
            station.setLineNumber(Integer.parseInt(split[1]));
            station.setColumnNumber(Integer.parseInt(split[2]));
            stationMapper.updateById(station);
        } else {
            // 新增
            station = stationMapper.selectOne(new QueryWrapper<Station>()
                    .eq("station_code", param.getStationCode())
                    .eq("station_name", param.getStationName()));
            if (station != null)
                return BizResult.fail("工位名称或工位编号已存在");

            String[] split = param.getStationCode().split("-");
            station = Station.builder()
                    .workshopId(param.getWorkshopId())
                    .stationName(param.getStationName())
                    .stationCode(param.getStationCode())
                    .lineNumber(Integer.parseInt(split[1]))
                    .columnNumber(Integer.parseInt(split[2]))
                    .build();

            stationMapper.insert(station);
        }
        commonUtil.updateStationInfo(station.getId(),
                StationVo.builder()
                        .id(station.getId())
                        .stationName(station.getStationName())
                        .stationCode(station.getStationCode())
                        .build());

        if (StringUtils.isBlank(param.getEquipmentId())) {
            // 解绑
            bindInfoMapper.delete(new QueryWrapper<BindInfo>().eq("station_id", station.getId()));
            commonUtil.removeBindInfo(station.getId());
        }else {
            // 绑定/修改
            BindInfo bindInfo = bindInfoMapper.selectOne(new QueryWrapper<BindInfo>().eq("station_id", station.getId()));
            if (bindInfo == null) {
                bindInfo = BindInfo.builder().stationId(station.getId()).equipmentId(param.getEquipmentId()).build();
                bindInfoMapper.insert(bindInfo);
            }else {
                if (!param.getEquipmentId().equals(bindInfo.getEquipmentId())) {
                    bindInfo.setEquipmentId(param.getEquipmentId());
                    bindInfoMapper.updateById(bindInfo);
                }
            }
            commonUtil.updateBindInfo(station.getId(), param.getEquipmentId());
        }

        return BizResult.success();
    }

    /**
     * 删除机台
     * @param stationId
     * @return
     */
    @Override
    @Transactional
    public BizResult<?> removeStation(String stationId) {
        Station station = stationMapper.selectById(stationId);
        if (station == null)
            return BizResult.success();

        stationMapper.deleteById(station.getId());
        groupStationMapper.delete(new QueryWrapper<GroupStation>().eq("station_id", station.getId()));
        commonUtil.removeStationInfo(station.getId());
        commonUtil.removeBindInfo(station.getId());

        return BizResult.success();
    }

    /**
     * 按条件分页查询工位信息
     * @param param
     * @return
     */
    @Override
    public BizResult<PageResult<StationDto>> stationPage(StationPageParam param) {
        QueryWrapper<Station> queryWrapper = new QueryWrapper<>();
        if (StringUtils.isNotBlank(param.getStationCode()))
            queryWrapper.like("station_code", param.getStationCode());
        if (StringUtils.isNotBlank(param.getStationName()))
            queryWrapper.like("station_name", param.getStationName());
        if (StringUtils.isNotBlank(param.getWorkshopId()))
            queryWrapper.eq("workshop_id", param.getWorkshopId());

        IPage<Station> page = stationMapper.selectPage(
                new Page<>(param.getCurrent(), param.getSize()),
                queryWrapper.orderByAsc("line_number", "column_number", "station_code"));

        IPage<StationDto> convert = page.convert(c ->{
            StationDto build = StationDto.builder()
                    .stationId(c.getId())
                    .stationName(c.getStationName())
                    .stationCode(c.getStationCode())
                    .columnNumber(c.getColumnNumber())
                    .lineNumber(c.getLineNumber())
                    .workshop(commonUtil.getWorkshopById(c.getWorkshopId()))
                    .equipmentId(commonUtil.getBindInfoById(c.getId()))
                    .build();
            EquipmentVo equipmentVo = commonUtil.getEquipmentById(build.getEquipmentId());
            build.setEquipmentName(equipmentVo.getEquipmentName());
            build.setTypeName(commonUtil.getEquipmentTypeById(equipmentVo.getEquipmentTypeId()));
            build.setModelName(commonUtil.getModelById(equipmentVo.getModelId()).getModelName());
            return build;
        });
        PageResult<StationDto> res = PageResult.<StationDto>builder()
                .current(convert.getCurrent())
                .pages(convert.getPages())
                .size(convert.getSize())
                .build();
        if (convert.getRecords().size() > 0) {
            convert.getRecords().sort(Comparator.comparing(c -> Integer.parseInt(c.getStationName())));
            res.setRecord(convert.getRecords());
        }
        return BizResult.success(res);
    }
}
